﻿using System;
using System.Web;
using System.Web.Routing;

namespace SlamCms.Web.Mvc
{
	public class NormalizeRoute : RouteBase
	{
		public NormalizeRoute(RouteBase route)
			: this(route, requireLowerCase: true, appendTrailingSlash: false)
		{
		}

		public NormalizeRoute(RouteBase route, bool requireLowerCase, bool appendTrailingSlash)
		{
			if (route == null)
			{
				throw new ArgumentNullException("route");
			}
			__DebugRoute = route;
			AppendTrailingSlash = appendTrailingSlash;
			RequireLowerCase = requireLowerCase;
		}

		// This is so the RouteDebugger reports on this correctly.
		// This name was chosen intentionally! Don't change it. :)
		internal RouteBase __DebugRoute
		{
			get;
			private set;
		}

		public bool AppendTrailingSlash
		{
			get;
			private set;
		}

		public bool RequireLowerCase
		{
			get;
			private set;
		}

		public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
		{
			var internalRoute = __DebugRoute as Route;
			if (internalRoute != null && !internalRoute.Url.Contains("{"))
			{
				return null;
			}

			var vpd = __DebugRoute.GetVirtualPath(requestContext, values);

			if (vpd != null)
			{
				var virtualPath = vpd.VirtualPath;
				if (RequireLowerCase)
				{
					virtualPath = virtualPath.ToLowerInvariant();
				}
				if (AppendTrailingSlash)
				{
					var queryIndex = virtualPath.IndexOf('?');
					string queryPart = string.Empty;
					if (queryIndex > -1)
					{
						queryPart = virtualPath.Substring(queryIndex);
						virtualPath = virtualPath.Substring(0, queryIndex);
					}
					if (!virtualPath.EndsWith("/"))
					{
						virtualPath = virtualPath + "/";
					}
					virtualPath += queryPart;
				}
				vpd.VirtualPath = virtualPath;
			}
			return vpd;
		}

		public override RouteData GetRouteData(HttpContextBase httpContext)
		{
			return __DebugRoute.GetRouteData(httpContext);
		}
	}
}
